package main

import (
	"fmt"
	"testing"
)

type Subject interface {
	Do() string
}

type RealSubject struct{}

func (RealSubject) Do() string {
	return "real"
}

type Proxy struct {
	real RealSubject
}

func (p Proxy) Do() string {
	var res string

	// 在调用真实对象之前的工作，检查缓存，判断权限，实例化真实对象等。。
	res += "pre:"

	// 调用真实对象
	res += p.real.Do()

	// 调用之后的操作，如缓存结果，对结果进行处理等。。
	res += ":after"

	return res
}

func main() {
	t := testing.T{}
	var sub Subject
	sub = &Proxy{} // 创建一个代理对象
	/*
		在对象工作之前和工作之后做一些处理
	*/
	res := sub.Do()
	if res != "pre:real:after" {
		t.Fail()
	} else {
		fmt.Println(res)
	}
}

/*
代理模式

代理模式的定义：
	由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时，访问对象不适合或者不能直接引用目标对象，代理对象作为访问对象和目标对象之间的中介。

代理模式的主要优点有：
	代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用；
	代理对象可以扩展目标对象的功能；
	代理模式能将客户端与目标对象分离，在一定程度上降低了系统的耦合度，增加了程序的可扩展性

其主要缺点是：
	代理模式会造成系统设计中类的数量增加
	在客户端和目标对象之间增加一个代理对象，会造成请求处理速度变慢；
	增加了系统的复杂度；


# 代理模式

代理模式用于延迟处理操作或者在进行实际操作前后进行其它处理。

## 代理模式的常见用法有

* 虚代理
* COW代理
* 远程代理
* 保护代理
* Cache 代理
* 防火墙代理
* 同步代理
* 智能指引

等。。。



*/
